// Common/QTime.h

#include "stdafx.h"
#include "time.h"


#include "qtime.h"
using namespace micro::utils;

///time_t,  FILETIME si TM SUNT IN FORMAT UNIVERSAL, GMT
//SYSTIME este in format local,
//PT AFISARE SE CONVERTESC IN  FORMAT LOCAL APOI IN SYSTIME APOI SE AFISEAZA


QTime::QTime() throw() :	m_time( 0 )
{

}


QTime::QTime( time_t time )  throw(): m_time( time )
{

}

QTime::QTime( int nYear, int nMonth, int nDay, int nHour, int nMin, int nSec,	int nDST )
{

    ASSERT( nYear >= 1900 );
    ASSERT( nMonth >= 1 && nMonth <= 12 );
//	ATLENSURE( nDay >= 1 && nDay <= 31 );
//	ATLENSURE( nHour >= 0 && nHour <= 23 );
//	ATLENSURE( nMin >= 0 && nMin <= 59 );
//	ATLENSURE( nSec >= 0 && nSec <= 59 );
//


    struct tm atm;

    atm.tm_sec = nSec;
    atm.tm_min = nMin;
    atm.tm_hour = nHour;
    atm.tm_mday = nDay;
    atm.tm_mon = nMonth - 1;        // tm_mon is 0 based
    atm.tm_year = nYear - 1900;     // tm_year is 1900 based
    atm.tm_isdst = nDST;



    m_time = _mktime64( &atm ); //il facee in format universal, gmt
    ASSERT( m_time != -1 );     // indicates an illegal input time

}


QTime::QTime( const SYSTEMTIME & sysTime, int nDST )
{
    if ( sysTime.wYear < 1900 )
    {
        m_time = 0;
    }
    else
    {
        QTime timeT(
            ( int )sysTime.wYear, ( int )sysTime.wMonth, ( int )sysTime.wDay,
            ( int )sysTime.wHour, ( int )sysTime.wMinute, ( int )sysTime.wSecond,
            nDST );
        *this = timeT;
    }
}

QTime::QTime( const FILETIME & fileTime, int nDST )
{
    // first convert file time (UTC time) to local time
    FILETIME localTime;

    if ( !FileTimeToLocalFileTime( &fileTime, &localTime ) )
    {
        m_time = 0;
        return;
    }


    // then convert that time to system time
    SYSTEMTIME sysTime;

    if ( !FileTimeToSystemTime( &localTime, &sysTime ) )
    {
        m_time = 0;

        return;
    }

    // then convert the system time to a time_t (C-runtime local time)
    QTime timeT( sysTime, nDST );
    *this = timeT;
}

QTime & QTime::operator=( time_t time ) throw()
{
    m_time = time;
    return *this;
}






void QTime::SystemTimeToTimet( const SYSTEMTIME * pTime, time_t & tim )
{

    tm tm = {0};

    tm.tm_year = pTime->wYear;
    tm.tm_mon = pTime->wMonth;
    tm.tm_mday = pTime->wDay;

    tm.tm_hour = pTime->wHour;
    tm.tm_min = pTime->wMinute;
    tm.tm_sec = pTime->wSecond;

    tim =  mktime( &tm );
}

void QTime::TimetToFileTime( const time_t t, FILETIME & ft )
{
    LONGLONG ll = Int32x32To64( t, 10000000 ) + 116444736000000000;
    ft.dwLowDateTime = ( DWORD ) ll;
    ft.dwHighDateTime = ll >> 32;
}

void QTime::FileTimeToTimet( const FILETIME & ft, time_t & tim )
{
    LARGE_INTEGER ull;
    ull.LowPart = ft.dwLowDateTime;
    ull.HighPart = ft.dwHighDateTime;

    tim =   ( ull.QuadPart  / 10000000ULL )  - 11644473600ULL;
}

//used by unrar
void  QTime::DosTimeToTimet( const unsigned int tim, time_t & time )
{
    FILETIME ft = {0};
    DosDateTimeToFileTime ( HIWORD( tim ), LOWORD( tim ), &ft );
    time = 0;
    FileTimeToTimet( ft, time );
}

void  QTime::ConvertTimeToString( const time_t time, QString & str,   bool includeTime, bool includeSeconds )
{

    FILETIME ftime;
    TimetToFileTime( time, ftime );

    ConvertTimeToString( ftime, str, includeTime, includeSeconds );

}

//deprecated
void  QTime::ConvertTimeToString( const FILETIME & ft, QString & str,   bool includeTime, bool includeSeconds )
{
	SYSTEMTIME st;
	FILETIME loc;


	FileTimeToLocalFileTime( &ft, &loc );

	///apoi
	if ( ! ::FileTimeToSystemTime( &loc, &st )  )   return ;

	str.Format( _T( "%04d-%02d-%02d" ), st.wYear, st.wMonth, st.wDay );

	if ( includeTime )
	{
		QString  time;
		time.Format( _T( " %02d:%02d" ), st.wHour, st.wMinute );
		str +=  time;

		if ( includeSeconds )
		{
			time.Format( _T( ":%02d" ), st.wSecond );
			str +=  time;
		}
	}

}



QTime QTime::GetCurrentTime() throw()
{
	/*

    	///conversie din time_t in tm
    	
    	time_t		tim;
		struct tm   tm1;
		

       time( &tim );
       _localtime64_s( &tm1, &tim );

     */


    ///conversie din tm in time_t
    ///struct tm t1;
    ///time_t mytime = mktime(&t1);



    time_t  tim;
	//Coordinated Universal Time (UTC)
    time( & tim );
	
    return QTime( tim );
}

// formatting using "C" strftime
QString  QTime::Format( LPCTSTR frm ) const
{
    QString str;

    if ( -1 == m_time )
        return str;

    TCHAR buf[100];
    ///TCHAR * local = L"%Y-%m-%d %H:%M:%S";
    TCHAR * local = L"%Y-%m-%d %H:%M";

    if ( nullptr == frm )
        frm = local;


    struct tm tm1;
    _localtime64_s( &tm1, &m_time );

    _tcsftime( buf, _countof( buf ), frm, &tm1 );
    str = buf;

    return str;
}

struct tm ltime( void )
{
    SYSTEMTIME st;
    struct tm tm;

    GetLocalTime( &st );
    tm.tm_sec = st.wSecond;
    tm.tm_min = st.wMinute;
    tm.tm_hour = st.wHour;
    tm.tm_mday = st.wDay;
    tm.tm_mon = st.wMonth - 1;
    tm.tm_year = ( st.wYear >= 1900 ? st.wYear - 1900 : 0 );
    tm.tm_wday = st.wDayOfWeek;
    tm.tm_yday = -1; /* GetLocalTime doesn't tell us */
    tm.tm_isdst = 0; /* GetLocalTime doesn't tell us */
    return tm;
}